#include "opmysql.h"

#include <mysql_driver.h>
#include <mysql_connection.h>
#include <cppconn/driver.h>
#include <cppconn/statement.h>
#include <fstream>
#include <sstream>
#include <string>
#include <stdio.h>
#include <boost/format.hpp>
#include <string>
#include "opmysql.h"
#include <iomanip>
#include "test.h"

using namespace std;

const string DBHOST =  "tcp://127.0.0.1:3306";
const string USER  = "root";
const string PASSWORD =  "123";

const char *TMP_FILE = "tmp.txt";




void test_mysql()
{
    sql::Driver  *driver;
    sql::Connection *conn;
    driver = get_driver_instance();
    
    // 连接
    conn = driver->connect(DBHOST, USER, PASSWORD);    
    cout << "Database connection autommit mode = " << conn->getAutoCommit() << endl;

    // 操作
    // auto query = conn->query("");

    // 断开
    conn->close();
    delete conn;
    driver = nullptr;
    conn = nullptr;
}


void test2_mysql()
{
    sql::Driver *mysql_driver;
    sql::Connection *mysql_conn;
    sql::Statement *msyql_statement;

    mysql_driver = get_driver_instance();
    mysql_conn = mysql_driver->connect(DBHOST, USER, PASSWORD);
    msyql_statement = mysql_conn->createStatement();


    msyql_statement->execute("use user;");
    auto res = msyql_statement->executeQuery("select * from student;");
    while (res->next())
    {
        cout << setw(10) << res->getInt("Sid");
        cout << setw(10) << res->getString("Sname").c_str();
        cout << setw(10) << res->getString("Sdept").c_str() << endl;
    }

    int cnt = test_fileIO();
    string sqlStr = (boost::format("INSERT INTO student VALUES ('123456%1%','Hello%1%',19,'S','MD8-%1%');") % cnt).str();
    cout << "sql statement: " << sqlStr << endl;
    // 插入
    // auto res2{msyql_statement->execute(sqlStr)};   // BUG record
    // auto prep_stmt = mysql_conn->prepareStatement(sqlStr);
    auto res2 = msyql_statement->executeUpdate(sqlStr);
    cout << "Insert Res: " << res2 << endl;

    // auto res2{msyql_statement->executeQuery("SELECT 'Welcome to Connector/C++' AS _message")};
    mysql_conn->close();
    if(mysql_conn->isClosed())
    {
        cout << "INFO: Mysql connection is closed!" << endl;
    }


    delete mysql_conn;
    mysql_driver = nullptr;
    mysql_conn = nullptr;
    msyql_statement = nullptr;


}
//  INSERT INTO `student` VALUES ('92345676','Hello6',19,'S','MD8-6');

int test_fileIO()
{
    fstream myFile;
    myFile.open(TMP_FILE,ios_base::in|ios_base::out);
    int num;
    if(myFile.is_open())
    {
        // doing
        myFile >> num;
        cout << "Reading from " << TMP_FILE << ", num is " << num << endl;
        myFile.close();
        myFile.open(TMP_FILE,ios_base::out|ios_base::trunc);
        if(myFile.is_open())
        {
            myFile << ++num;
            myFile.close();
        }
    }else {
        cout << TMP_FILE << " does not being opened!" << endl;
    }
    return num;
}

void test_fstreamNewFile()
{
    string local = "/home/doit/Desktop/123.txt";
    ofstream outfile(local);
    if(outfile.is_open())
    {
        // outfile << "hello" << endl;
        outfile.close();
    }else 
    {
        cout << "creat file fail " << local;
    }

}


int test_string() {
    int a = 10;
    float b = 20.5f;
    // boost::format fmt("整数是：%1%, 浮点数是：%2%");
    // std::string result = fmt % a % b;
    string str = (boost::format("int is: %1%") % a).str();
    // cout << 
    // 使用result
    return 0;
}




void OpMysqlTest1()
{
    OpMysql op(DBHOST, USER, PASSWORD);
    OpState opst;
    opst = op.connect();
    cout << "state:" << opst << endl;

    if(opst < DRIVER_UP)
    {
        cout << "CONNECT FAIL! Break." << endl;
    }

    opst = op.execute("use user;");
    cout << "state:" << opst << endl;

    int cnt = test_fileIO();
    string sqlStr = (boost::format("INSERT INTO student VALUES ('123456%1%','Hello%1%',19,'S','MD8-%1%');") % cnt).str();
    cout << "statement: " << sqlStr << endl;
    opst = op.execute(sqlStr);
    cout << "state:" << opst << endl;

    op.executeQueue("select Sname from student;");
    if(op.res != nullptr)
    {
        while(op.res->next())
        {
            cout << setw(10) << op.res->getString("Sname").c_str() << endl;
        }
    }
}


enum advice_level {
	ADVICE_LEVEL_NONE = 0,
	ADVICE_LEVEL_DISABLED,
	ADVICE_LEVEL_ENABLED,
};

static struct ADV {
	const char *key;
	enum advice_level level;
}advice_setting[] = {
	[ADVICE_ADD_EMBEDDED_REPO]			= { "addEmbeddedRepo" },
    [ADVICE_ADD_EMPTY_PATHSPEC]			= { "addEmptyPathspec" },
	[ADVICE_ADD_IGNORED_FILE]			= { "addIgnoredFile" },
	[ADVICE_AMBIGUOUS_FETCH_REFSPEC]	= { "ambiguousFetchRefspec" },
};


int arrayNewInit[] = {
    [0] = 0,
    [1] = 1,
    [2] = 2,
    [3] = 3,
    [4] = 4,
};

struct {
    int num;
}arrayStructNewInit[] = {
    [0] = {0},
    [1] = {1},
    [2] = {2},
    [3] = {3},
    [4] = {4},
};





void structADVExplore()
{
    // advice_setting->key
    // advice_setting[0].
    for(int i = 0; i < 4; ++i)
        cout << arrayNewInit[i] << endl;
}